#include "FuncFiller.H"
#include "Circle.H"
#include "EmbeddedGrid.H"
#include "DirectPossionSolver.H"
#include "MyFunctions.H"

template<class VecExpr,class ScalerExpr>
void testExample(const ScalerExpr &negDDexpr,const ScalerExpr &expr,const VecExpr &Dexpr,const char *aBcTypes, int N = 8)
{
  char bcTypes[10];
  strncpy(bcTypes, aBcTypes, 10);
  Box<Dim> b1(0, N);
  RectDomain<Dim> pGrid(Box<Dim>(0, N), 1.0 / N);
  ExcludedCircle<2> rce1(pGrid, (OrientedCircle){{0.4, 0.5}, 0.2},1e-15);
  FuncFiller<Dim> ff(pGrid);
  Box<Dim> gbx = pGrid;
  Tensor<Real, Dim> phi(gbx);
  Tensor<Real, Dim - 1> bcData[2 * Dim];
  loop_box_2(gbx,i,j)
    ff.fillDomainVal(phi,negDDexpr);
  for (int d = 0; d < Dim; ++d)
  {
    for (int side : {-1, 1})
    {
      int m = 2 * d + (side + 1) / 2;
      switch (bcTypes[m])
      {
      case 'D':
      {
          bcData[m].resize(reduce(gbx, m / 2));
          // std::cout<<bcData[m].box().volume()<<",this is "<<m<<"\n";
          ff.fillRectBdrVal(bcData[m], d, side, expr);
          break;
      }
      case 'N':
      {
          bcData[m].resize(reduce(gbx, m / 2));
          ff.fillRectBdrNormalGrad(bcData[m],d,side,Dexpr);
        break;          
      }
      default:
        break;
      }
    }
  }
  switch (bcTypes[4])
  {
  case 'D':
  {
    DirectPossionSolver<2> DPS1(rce1, bcTypes,bcData,phi,expr);  
    std::cout<<"N = "<<N<<", "<<DPS1.computeErrNorm(expr,0)<<'\n';
    //DPS1.plotIn("fileExample.m",expr);      
    break;
  }
  case 'N':{
    DirectPossionSolver<2> DPS1(rce1, bcTypes,bcData,phi,[&](const auto &x){return dot(Dexpr(x),rce1.embeddingCircle.getNormalGrad(x));});
    std::cout<<"N = "<<N<<", "<<DPS1.computeErrNorm(expr,0)<<'\n';
    //DPS1.plotIn("fileExample.m",expr);
    break;
  }
  default:
    break;
  }
}

//----------------------------------------------------------------

int main()
{
  for(int i:{8,16,32,64})
  {
    testExample(negDDEXPT1,EXPT1,DEXPT1,"DDDDN",i);
  }
    for(int i:{8,16,32,64})
  {
    testExample(negDDEXPT1,EXPT1,DEXPT1,"DDDND",i);
  }

}

